﻿using Jellyfin.Plugin.JavMetadata.Dto;
using Jellyfin.Plugin.JavMetadata.Service;
using Jellyfin.Plugin.JavMetadata.Site.Avmoo.Service;
using Jellyfin.Plugin.JavMetadata.Site.Avsox.Dto;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Movies;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Providers;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace Jellyfin.Plugin.JavMetadata.Site.Avsox.Service
{
    public class AvsoxHttpService : HttpService
    {
        private readonly ILogger<AvsoxHttpService> _logger;
        private readonly IHttpClientFactory _http;

        public AvsoxHttpService(ILogger<AvsoxHttpService> logger, IHttpClientFactory http) : base(logger, http)
        {
            _http = http;
            _logger = logger;
        }

        public override async Task<T> GetMovieAsync<T>(string id, CancellationToken cancellationToken)
        {
            // id 不能为空
            if (string.IsNullOrWhiteSpace(id))
            {
                _logger.LogError("id is null.");
                throw new ArgumentException("sid is empty when getting subject");
            }

            // 详情页 url
            var url = $"https://{Plugin.Instance.Configuration.Avsox.Domain}/{Plugin.Instance.Configuration.Avsox.Language.ToString().ToLower()}/movie/{id}";

            // 拉取 html
            var html = await GetHtmlAsync(url, cancellationToken);

            var item = new MovieItem();

            // 识别码
            string avid = string.Empty;
            // 影片标题
            var title = await GetTitleAsync(html, cancellationToken);
            // 找到第一个空格, 拆分识别码与标题
            var splitIndex = title.IndexOf(' ');
            // 如果有值说明符合格式
            if (splitIndex > 1)
            {
                avid = title[..splitIndex];
                title = title[splitIndex..];
            }

            var fanart = await GetFanartAsync(html, cancellationToken);
            item.Avid = avid;
            item.Title = title;
            item.Poster = await GetPosterAsync(avid, cancellationToken);
            item.Fanart = fanart;
            item.ReleaseDate = GetReleaseDate(html);
            item.Duration = GetDuration(html);
            item.Directors = await GetDirectorsAsync(html, cancellationToken);
            item.Studios = await GetStudiosAsync(html, cancellationToken);
            item.Labels = await GetLabelsAsync(html, cancellationToken);
            item.Series = await GetSeriesAsync(html, cancellationToken);
            item.Genres = await GetGenresAsync(html, cancellationToken);
            item.Actresses = await GetActressesAsync(html, cancellationToken);
            item.SourceUrl = url;
            return item as T;
        }

        public override async Task<MetadataResult<Movie>> GetMovieMetadataAsync(string id, CancellationToken cancellationToken)
        {
            var result = new MetadataResult<Movie>();

            // 如果 id 为空，则直接返回空结果
            if (string.IsNullOrWhiteSpace(id))
            {
                _logger.LogError("sid is empty when getting subject.");
                return result;
            }

            // 获取影片详情
            var item = await GetMovieAsync<MovieItem>(id, cancellationToken);

            // 设置 基础信息
            var movie = new Movie
            {
                Name = item.Title,
                OriginalTitle = $"{item.Avid} {item.Title}",
                SortName = item.Avid,
                ForcedSortName = item.Title,
                //Overview = detail.Intro, // 无
                HomePageUrl = $"https://{Plugin.Instance.Configuration.Avsox.Domain}/{Plugin.Instance.Configuration.Avsox.Language.ToString().ToLower()}/movie/{id}"
            };

            // 如果 系列 不为空
            if (item.Series?.Count > 0)
            {
                // 设置合集名
                movie.CollectionName = item.Series?[0];
            }

            // 如果 发行日期 不为空
            if (item.ReleaseDate != null)
            {
                var releaseDate = item.ReleaseDate?.ToUniversalTime();

                // 设置 发行日期
                movie.PremiereDate = releaseDate;
                // 设置 年份
                movie.ProductionYear = releaseDate?.Year;
            }

            // 添加 类别
            item.Genres.ForEach((item) =>
            {
                movie.AddGenre(item);
            });

            // 添加 工作室
            item.Studios.ForEach((studio) =>
            {
                movie.AddStudio(studio);
            });

            // 添加 发行商
            item.Labels.ForEach((label) =>
            {
                // 不存在时才添加
                if (!movie.Studios.Contains(label))
                {
                    movie.AddStudio(label);
                }
            });

            // 添加 导演
            (await TransPersonInfoAsync(item.Directors, PersonType.Director, cancellationToken))?.ForEach((item) =>
            {
                result.AddPerson(item);
            });

            // 添加 演员
            (await TransPersonInfoAsync(item.Actresses, PersonType.Actor, cancellationToken))?.ForEach((item) =>
            {
                result.AddPerson(item);
            });

            // 添加 编剧
            //await TransPersonInfoAsync(movie.Writers, PersonType.Writer, cancellationToken).ForEach(result.AddPerson);

            result.QueriedById = false;
            result.HasMetadata = true;
            result.Item = movie;

            return result;
        }

        /// <summary>
        /// 根据关键字搜索影片，并取得搜索结果列表。
        /// 例如 /search/TEST-001 中的 TEST-001
        /// </summary>
        /// <param name="key"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public override async Task<IEnumerable<T>> SearchAsync<T>(string keyword, CancellationToken cancellationToken)
        {
            var results = new List<T>();

            // 查找页 url
            var url = $"https://{Plugin.Instance?.Configuration.Avsox.Domain}/{Plugin.Instance?.Configuration.Avsox.Language.ToString().ToLower()}/search/{keyword}";

            // 拉取 html
            var html = await GetHtmlAsync(url, cancellationToken);

            // 匹配影片
            var matches = Regex.Matches(html, Plugin.Instance.Configuration.Avsox.SearchResultPattern); //@"/movie/([\d\w]+)"

            foreach (Match match in matches)
            {
                if (match.Success)
                {
                    var item = new AvsoxSearchResult { Id = match.Groups["id"].Value.Trim(), Avid = match.Groups["avid"].Value.Trim(), Poster = match.Groups["poster"].Value.Trim() };
                    results.Add(item as T);
                }
            }

            // 返回 30 条记录
            return (IEnumerable<T>)results.Distinct().Take(30).ToList();
        }

        /// <summary>
        /// 获取标题
        /// </summary>
        /// <param name="html"></param>
        /// <returns></returns>
        public async Task<string> GetTitleAsync(string html, CancellationToken cancellationToken)
        {
            return await Task.Run(() =>
            {
                var match = Regex.Match(html, Plugin.Instance.Configuration.Avsox.TitlePattern);

                if (match.Success)
                {
                    var title = match.Groups["title"].Value.Trim();
                    return title;
                }
                return string.Empty;
            }, cancellationToken);
        }

        /// <summary>
        /// 获取小封面 URL，
        /// 由于 AvSox 大小封面的 URL 没有规律，
        /// 只能通过搜索页重新搜索 识别码 来获取小封面
        /// </summary>
        /// <param name="id">识别码</param>
        /// <returns></returns>
        public async Task<string?> GetPosterAsync(string id, CancellationToken cancellationToken)
        {
            var items = await SearchAsync<AvsoxSearchResult>(id, cancellationToken).ConfigureAwait(false);

            var item = items.SingleOrDefault(x => x.Avid.ToUpper() == id.ToUpper());

            return item?.Poster;
        }

        /// <summary>
        /// 获取大封面 URL
        /// </summary>
        /// <param name="html"></param>
        /// <returns></returns>
        public async Task<string> GetFanartAsync(string html, CancellationToken cancellationToken)
        {
            return await Task.Run(() =>
            {
                var match = Regex.Match(html, Plugin.Instance.Configuration.Avsox.CoverPattern); //@"bigImage""\shref=""(?<large>.*?)"""

                if (match.Success)
                {
                    return match.Groups["fanart"].Value.Trim();
                }
                return string.Empty;
            }, cancellationToken);
        }

        /// <summary>
        /// 获取发行日期
        /// </summary>
        /// <param name="html"></param>
        /// <returns></returns>
        public DateTime? GetReleaseDate(string html)
        {
            var match = Regex.Match(html, Plugin.Instance.Configuration.Avsox.ReleaseDatePattern); //@"发行时间:</span>\s(?<date>.*?)</p>"
            if (match.Success)
            {
                DateTime.TryParse(match.Groups["date"].Value.Trim(), out DateTime date);
                return date;
            }
            return null;
        }

        /// <summary>
        /// 获取时长
        /// </summary>
        /// <param name="html"></param>
        /// <returns></returns>
        public int GetDuration(string html)
        {
            var match = Regex.Match(html, Plugin.Instance.Configuration.Avsox.DurationPattern); //@"长度:</span>\s(?<duration>\d+)"
            if (match.Success)
            {
                int.TryParse(match.Groups["duration"].Value.Trim(), out int duration);
                return duration;
            }

            return 0;
        }

        /// <summary>
        /// 获取导演列表
        /// </summary>
        /// <param name="html"></param>
        /// <returns></returns>
        public async Task<List<PersonModel>> GetDirectorsAsync(string html, CancellationToken cancellationToken)
        {
            var list = new List<PersonModel>();
            return await Task.Run(() =>
            {
                var match = Regex.Match(html, Plugin.Instance.Configuration.Avsox.DirectorListPattern); //@"导演:</span>\s(?<directors>.*?)</p>"
                if (match.Success)
                {

                    var items = Regex.Matches(match.Groups["directors"].Value.Trim(), Plugin.Instance.Configuration.Avsox.DirectorPattern); //"href=\"(?<url>.*?)\">(?<name>.*?)<"
                    foreach (Match item in items)
                    {
                        if (item.Success)
                        {
                            list.Add(new PersonModel
                            {
                                Name = item.Groups["name"].Value.Trim(),
                                Alt = item.Groups["url"].Value.Trim()
                            });
                        }
                    }
                    items = null;
                }

                return list;
            }, cancellationToken);
        }

        /// <summary>
        /// 获取工作室列表
        /// </summary>
        /// <param name="html"></param>
        /// <returns></returns>
        public async Task<List<string>> GetStudiosAsync(string html, CancellationToken cancellationToken)
        {
            var list = new List<string>();
            return await Task.Run(() =>
            {
                var match = Regex.Match(html, Plugin.Instance.Configuration.Avsox.StudioListPattern); //@"制作商:\s</p>\s*<p>(?<studios>.*?)\s*</p>"
                if (match.Success)
                {
                    var items = Regex.Matches(match.Groups["studios"].Value.Trim(), Plugin.Instance.Configuration.Avsox.StudioPattern); //"href=\"(?<url>.*?)\">(?<name>.*?)<"
                    foreach (Match item in items)
                    {
                        if (item.Success)
                        {
                            list.Add(item.Groups["name"].Value.Trim());
                        }
                    }
                }

                return list;
            }, cancellationToken);
        }

        /// <summary>
        /// 获取发行商列表
        /// </summary>
        /// <param name="html"></param>
        /// <returns></returns>
        public async Task<List<string>> GetLabelsAsync(string html, CancellationToken cancellationToken)
        {
            var list = new List<string>();
            return await Task.Run(() =>
            {
                var match = Regex.Match(html, Plugin.Instance.Configuration.Avsox.LabelListPattern); //@"发行商:\s</p>\s*<p>(?<labels>.*?)\s*</p>"
                if (match.Success)
                {
                    var items = Regex.Matches(match.Groups["labels"].Value.Trim(), Plugin.Instance.Configuration.Avsox.LabelPattern); //"href=\"(?<url>.*?)\">(?<name>.*?)<"
                    foreach (Match item in items)
                    {
                        if (item.Success)
                        {
                            list.Add(item.Groups["name"].Value.Trim());
                        }
                    }
                }

                return list;
            }, cancellationToken);
        }

        /// <summary>
        /// 获取系列列表
        /// </summary>
        /// <param name="html"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async Task<List<string>> GetSeriesAsync(string html, CancellationToken cancellationToken)
        {
            var list = new List<string>();
            return await Task.Run(() =>
            {
                var match = Regex.Match(html, Plugin.Instance.Configuration.Avsox.CollectionListPattern);
                if (match.Success)
                {
                    var items = Regex.Matches(match.Groups["series"].Value.Trim(), Plugin.Instance.Configuration.Avsox.CollectionPattern);
                    foreach (Match item in items)
                    {
                        if (item.Success)
                        {
                            list.Add(item.Groups["name"].Value.Trim());
                        }
                    }
                }

                return list;
            }, cancellationToken);
        }

        /// <summary>
        /// 获取风格列表
        /// </summary>
        /// <param name="html"></param>
        /// <returns></returns>
        public async Task<List<string>> GetGenresAsync(string html, CancellationToken cancellationToken)
        {
            var list = new List<string>();
            return await Task.Run(() =>
            {
                var match = Regex.Match(html, Plugin.Instance.Configuration.Avsox.GenreListPattern); //@"类别:</p>\s*<p>(?<genres>.*?)\s*</p>"
                if (match.Success)
                {
                    var items = Regex.Matches(match.Groups["genres"].Value, Plugin.Instance.Configuration.Avsox.GenrePattern); //"href=\"(?<url>.*?)\">(?<name>.*?)<"
                    foreach (Match item in items)
                    {
                        if (item.Success)
                        {
                            list.Add(item.Groups["name"].Value.Trim());
                        }
                    }
                }

                return list;
            }, cancellationToken);
        }

        /// <summary>
        /// 获取演员列表
        /// </summary>
        /// <param name="html">html 内容</param>
        /// <returns></returns>
        public async Task<List<PersonModel>> GetActressesAsync(string html, CancellationToken cancellationToken)
        {
            var list = new List<PersonModel>();
            return await Task.Run(() =>
            {
                var match = Regex.Match(html, Plugin.Instance.Configuration.Avsox.ActressListPattern); //@"avatar-waterfall"">\s*(?<actresses>[\w\W]*?)\s*</div>\s*<div"
                if (match.Success)
                {
                    var items = Regex.Matches(match.Groups["actresses"].Value, Plugin.Instance.Configuration.Avsox.ActressPattern); //@"href=""(?<url>.*?)""[\w\W]*?src=""(?<photo>.*?)""[\w\W]*?<span>(?<name>.*?)<"
                    foreach (Match item in items)
                    {
                        if (item.Success)
                        {
                            list.Add(new PersonModel
                            {
                                Name = item.Groups["name"].Value.Trim(),
                                Avatars = new PersonAvatar { Photo = item.Groups["photo"].Value.Trim() },
                                Alt = item.Groups["url"].Value.Trim()
                            });
                        }
                    }
                }

                return list;
            }, cancellationToken);
        }

        /// <summary>
        /// 转换 Dto 到 人员列表
        /// </summary>
        /// <param name="people"></param>
        /// <param name="personType"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async Task<List<PersonInfo>> TransPersonInfoAsync(List<PersonModel> people, string personType, CancellationToken cancellationToken)
        {
            return await Task.Run(() =>
            {
                var result = new List<PersonInfo>();

                foreach (var person in people)
                {
                    var photo = person.Avatars?.Photo;
                    var personInfo = new PersonInfo
                    {
                        Name = person.Name, // 姓名
                        Role = person.Name, // 饰演的角色
                        Type = personType,
                        ImageUrl = photo.EndsWith("nowprint.gif") == true ? null : photo // 如果没有照片，则不显示
                    };

                    personInfo.SetProviderId($"{Plugin.Instance?.Configuration.Avsox.ProviderName} Id", person.Id);
                    result.Add(personInfo);
                }

                return result;

            }, cancellationToken);
        }

        /// <summary>
        /// 将 Dto 转为 Movie
        /// </summary>
        /// <param name="detail"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async Task<Movie> TransMediaInfoAsync(MovieItem detail, CancellationToken cancellationToken)
        {
            return await Task.Run(() =>
            {
                // 设置 基础信息
                var movie = new Movie
                {
                    Name = detail.Title,
                    OriginalTitle = $"{detail.Avid} {detail.Title}",
                    SortName = detail.Avid,
                    ForcedSortName = detail.Avid,
                    Overview = detail.Intro,
                    HomePageUrl = detail.SourceUrl
                };

                // 如果 发行日期 不为空
                if (detail.ReleaseDate != null)
                {
                    var releaseDate = detail.ReleaseDate?.ToUniversalTime();

                    // 设置 发行日期
                    movie.PremiereDate = releaseDate;
                    // 设置 年份
                    movie.ProductionYear = releaseDate?.Year;
                }

                // 添加类别
                detail.Genres.ForEach((item) =>
                {
                    movie.AddGenre(item);
                });

                // 添加 工作室
                detail.Studios.ForEach((studio) =>
                {
                    movie.AddStudio(studio);
                });

                // 添加 发行商
                detail.Labels.ForEach((label) =>
                {
                    // 不存在时才添加
                    if (!movie.Studios.Contains(label))
                    {
                        movie.AddStudio(label);
                    }
                });

                return movie;

            }, cancellationToken);
        }
    }
}
